/***
 Base on Wrapper/Helper Class for datagrid based on jQuery Datatable Plugin
 ***/
var Datatable = function() {
    var tableOptions; // main options
    var dataTable; // datatable object
    var table; // actual table jquery object
    var tableContainer; // actual table container object
    var tableWrapper; // actual table wrapper jquery object
    var tableGroupActions; // table group actions wrapper jquery object
    var tableInitialized = false;
    var ajaxParams = {}; // set filter mode
    var the;

    var countSelectedRecords = function() {
        var selected = $('tbody > tr > td:nth-child(1) input[type="checkbox"]:checked', table).length;
        var text = tableOptions.dataTable.language.metronicGroupActions;
        if (selected > 0) {
            $('.table-group-actions > span', tableWrapper).text(text.replace("_TOTAL_", selected));
        } else {
            $('.table-group-actions > span', tableWrapper).text("");
        }
    };

    // quick search & column search
    var quick_search_dom = `<'row'<'col-sm-12 col-md-8 table-group-actions'><'col-sm-12 col-md-4'f>><'row'<'col-sm-12'tr>><'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7 dataTables_pager'lp>>`;

    // search filters
    var search_filter_dom = `<'row'<'col-sm-12'tr>><'row'<'col-sm-12 col-md-4'i><'col-sm-12 col-md-8 dataTables_pager'lp>>`;

    return {
        init: function(options) {
            if (!$().dataTable) {
                return;
            }
            the = this;

            var quickSearchFilter = options.quickSearchFilter;
            var dom = quickSearchFilter ? quick_search_dom : search_filter_dom;
            // default settings
            options = $.extend(true, {
                src: "", // actual table
                resetGroupActionInputOnSuccess: true,
				dataTable: {
                    //== Pagination settings
                    // read more: https://datatables.net/examples/basic_init/dom.html
                    dom: dom,
                    lengthMenu: [5, 10, 25, 50],
                    pageLength: 10,
                    responsive: true,
                    searchDelay: 500,
                    processing: true,
                    serverSide: true,
                    language:
                        /*$.i18n.datatable.language ? $.i18n.datatable.language : */
                            { // language settings
                        // metronic spesific
                        "metronicGroupActions": "_TOTAL_ records selected  ",
                        "metronicAjaxRequestGeneralError": "Could not complete request. Please check your internet connection",

                        // data tables spesific
                        //"lengthMenu": "<span class='seperator'>|</span>View _MENU_ records",
                        //"info": "<span class='seperator'>|</span>Found total _TOTAL_ records",
                        "infoEmpty": "No records found to show",
                        "emptyTable": "No data available in table",
                        "zeroRecords": "No matching records found",
                        /*"paginate": {
                            "previous": "Prev",
                            "next": "Next",
                            "last": "Last",
                            "first": "First",
                            "page": "Page",
                            "pageOf": "of"
                        }*/
                    },
					ajax: {
                    	"url": "", //actual url
                        "type": "POST", // request type
                        "dataType": "json",
                        "headers":{ ajax : true },
                        "data": function(data) { // add request parameters before submit

                            $.each(ajaxParams, function(key, value) {
                                data[key] = value;
                            });

                            //add for quick-search
                            var quickSearchFilter = table.data("datatable-quick-search-filter");
                            if (quickSearchFilter) {
                                data[quickSearchFilter] = data.search.value;
                            }

                            /*App.blockUI({
                                message: tableOptions.loadingMessage,
                                target: tableContainer,
                                overlayColor: 'none',
                                cenrerY: true,
                                boxed: true
                            });*/
                        },
                        dataSrc: function(res) { // Manipulate the data returned from the server
                            /*if (res.customActionMessage) {
                                App.alert({
                                    type: (res.customActionStatus == 'OK' ? 'success' : 'danger'),
                                    icon: (res.customActionStatus == 'OK' ? 'check' : 'warning'),
                                    message: res.customActionMessage,
                                    container: tableWrapper,
                                    place: 'prepend'
                                });
                            }*/

                            /*if (res.customActionStatus) {
                                if (tableOptions.resetGroupActionInputOnSuccess) {
                                    $('.table-group-action-input', tableWrapper).val("");
                                }
                            }*/

                            /*if ($('.group-checkable', table).size() === 1) {
                                $('.group-checkable', table).attr("checked", false);
                                //$.uniform.update($('.group-checkable', table));
                            }

                            */

                            if (tableOptions.onSuccess) {
                                tableOptions.onSuccess.call(undefined, the, res);
                            }

                            //App.unblockUI(tableContainer);
                            if(res.extraData){
                                $(table).data("extraData", res.extraData);
                            }
                            return res.data;
                        },
					},
                    drawCallback: function(oSettings) { // run some code on table redraw
                        if (tableInitialized === false) { // check if table has been initialized
                            tableInitialized = true; // set table initialized
                            table.show(); // display table
                        }
                        countSelectedRecords(); // reset selected records indicator

                        // callback for ajax data load
                        if (tableOptions.onDataLoad) {
                            tableOptions.onDataLoad.call(undefined, the);
                        }

                        if(tableOptions.dataTable.customDrawCallback){
                            tableOptions.dataTable.customDrawCallback.call(undefined, the, table);
                        }
                    }
				}
            }, options);

            tableOptions = options;

			// create table's jquery object
            table = $(options.src);
            tableContainer = table.parents(".table-container");

			// initialize a datatable
            dataTable = table.DataTable(options.dataTable);

            // get table wrapper, should after init
            tableWrapper = table.parents('.dataTables_wrapper');
            // build table group actions panel

            tableGroupActions = $('.table-group-actions', tableWrapper);
            if ($('.table-actions-wrapper', tableContainer).length === 1) {
                $('.table-group-actions', tableWrapper).html($('.table-actions-wrapper', tableContainer).html()); // place the panel inside the wrapper
                $('.table-actions-wrapper', tableContainer).remove(); // remove the template container
                // move the button group stuff into more btn-group
                var customBtnGroups = $('.table-group-actions', tableWrapper).find(".btn-group-items");
                var btnGroupMore = $('.table-group-actions', tableWrapper).find(".btn-group-more");
                if(btnGroupMore && customBtnGroups && customBtnGroups.length > 0){
                    btnGroupMore.prepend(customBtnGroups.html());
                    customBtnGroups.remove();
                }
            }


            var $searchFilters = tableContainer.find(".search-filters");
            $searchFilters.on('click', '.filter-submit', function(e) {
                e.preventDefault();
                the.submitFilter($searchFilters);
            });

            $searchFilters.on('click', '.filter-cancel', function(e) {
                e.preventDefault();
                the.resetFilter($searchFilters);
            });

            // handle filter submit button click
            table.on('click', '.filter-submit', function(e) {
                e.preventDefault();
                the.submitFilter();
            });

            // handle filter cancel button click
            table.on('click', '.filter-cancel', function(e) {
                e.preventDefault();
                the.resetFilter();
            });
        },

        submitFilter: function(container) {
            container = container ? container: table;
            // get all typeable inputs
            $('textarea.form-filter, select.form-filter, input.form-filter:not([type="radio"],[type="checkbox"])', container).each(function() {
                the.setAjaxParam($(this).attr("name"), $(this).val());
            });

            // get all checkboxes
            $('input.form-filter[type="checkbox"]:checked', container).each(function() {
                the.addAjaxParam($(this).attr("name"), $(this).val());
            });

            // get all radio buttons
            $('input.form-filter[type="radio"]:checked', container).each(function() {
                the.setAjaxParam($(this).attr("name"), $(this).val());
            });

            dataTable.ajax.reload();
        },

        resetFilter: function(container) {
            container = container ? container: table;
            $('textarea.form-filter, select.form-filter, input.form-filter', container).each(function() {
                $(this).val("");
            });
            $('input.form-filter[type="checkbox"]', container).each(function() {
                $(this).attr("checked", false);
            });
            the.clearAjaxParams();
            dataTable.ajax.reload();
        },

        getSelectedRowsCount: function() {
            return $('tbody > tr > td:nth-child(1) input[type="checkbox"]:checked', table).length;
        },

        getSelectedRows: function() {
            var rows = [];
            $('tbody > tr > td:nth-child(1) input[type="checkbox"]:checked', table).each(function() {
                rows.push($(this).val());
            });

            return rows;
        },

        setAjaxParam: function(name, value) {
            if (!name) return;
            ajaxParams[name] = value;
        },

        addAjaxParam: function(name, value) {
            if (!name) return;
            if (!ajaxParams[name]) {
                ajaxParams[name] = [];
            }

            var skip = false;
            for (var i = 0; i < (ajaxParams[name]).length; i++) { // check for duplicates
                if (ajaxParams[name][i] === value) {
                    skip = true;
                }
            }

            if (skip === false) {
                ajaxParams[name].push(value);
            }
        },

        clearAjaxParams: function(name, value) {
            ajaxParams = {};
        },

        getDataTable: function() {
            return dataTable;
        },

        getTableGroupActions: function(){
            return tableGroupActions;
        },

        getTableWrapper: function() {
            return tableWrapper;
        },

        getTableContainer: function() {
            return tableContainer;
        },

        getTable: function() {
            return table;
        },

        getSelectedRowIds: function(){
            var ids = [];
            $.each(the.getDataTable().rows('.active').data(), function(i, e){
                ids.push(e.id);
            });
            return ids;
        },

        getSerializeSelectedRowIds: function (key) {
            key = key ? key : "ids";
            var idsString = '';
            $.each(the.getSelectedRowIds(), function (i, e) {
                idsString += '&' + key + '=' + e;
            })
            return idsString.substring(1);
        },

        alertNoRecordSelected: function(){
            alert($.i18n.datatable.noRecordSelected);
            /*App.alert({
                type: 'danger',
                icon: 'warning',
                message: $.i18n.datatable.noRecordSelected,
                container: the.getTableWrapper(),
                place: 'prepend',
                closeInSeconds: 3
            });*/
        },
    }
};

(function($) {
    var initPickers = function () {
        //init date pickers
        $('.date-picker').datepicker({
            autoclose: true
        });
    }

    var defaultRenders = {
        'renderDate' : function ( data, type, full, meta ){
            return data?new Date(data).toString('yyyy-MM-dd'):'';
        },
        'renderTime' : function ( data, type, full, meta ){
            return data?new Date(data).toString('HH:mm:ss'):'';
        },
        'renderDateTime' : function ( data, type, full, meta ){
            return data?new Date(data).toString('yyyy-MM-dd HH:mm:ss'):'';
        },
        'renderBoolean' : function ( data, type, full, meta ){
            if(data){
                return $.i18n.datatable.yes;
            } else {
                return $.i18n.datatable.no;
            }
        }
    };

    var defaultActionBtnSettings = {
        "view" : function(grid, $table, $button, rowIndex, rowData){
            console.log('view', grid, $table, $button, rowIndex, rowData);
            //window.location.href = window.location.pathname + "/" + rowData.id;
        },
        "edit" : function(grid, $table, $button, rowIndex, rowData){
            console.log('edit', grid, $table, $button, rowIndex, rowData);
            //window.location.href = window.location.pathname + "/" + rowData.id + "/update";
        },
        "delete" : function(grid, $table, $button, rowIndex, rowData){
            console.log('delete', grid, $table, $button, rowIndex, rowData);
            /*$.mms.confirm({
                type: 'type-danger',
                title: $.i18n.confirmToDelete,
                message: $.i18n.confirmToDelete,
                ok: function(){
                    window.location.href = window.location.pathname + "/" + rowData.id + "/delete";
                }
            });*/
        }
    }

    var getActionBtnCallback = function ($button) {
        var action = $button.data("action");
        if (typeof window[action] === "function") {
            return window[action];
        }
        var type = $button.data("type");
        if (type) {
            if (type == 'update') type = 'edit';
            var actionBtnCallback = defaultActionBtnSettings[type];
            if (actionBtnCallback) {
                return actionBtnCallback;
            }
        }
        return function (grid, $table, $button, rowIndex, rowData) {
            // do nothing here
        };
    }

    var buildActionBtnRender = function (grid, $table){
        $table.on("click", "tbody tr a[data-type],tbody tr button[data-type]", function() {
            var $button = $(this);
            var rowIndex = $table.find("tbody tr").index($button.parents("tr"));
            var rowData = grid.getDataTable().row(rowIndex).data();
            var actionCallback = getActionBtnCallback($button);
            if (actionCallback) {
                actionCallback.call(undefined, grid, $table, $button, rowIndex, rowData);
            }
            $table.trigger("action.mdt.row.button", [grid, $table, $button, rowIndex, rowData]);
        });

        var $columnActions = $(".table-column-actions", grid.getTableContainer());
        return function( data, type, full, meta ){
            return $columnActions.html();
        };
    };

    function createColumnsOptions(grid, $table){
        var columns = [];
        $table.find("thead>tr.heading>th").each(function(i, e) {
            var columnConfig = $.extend(true, {
                searchable : true,
                orderable : true,
                data : null,
                defaultContent : ""
            }, $(this).data());

            if (columnConfig.checkable) {
                columnConfig.searchable = false;
                columnConfig.orderable = false;
                columnConfig.render = function( data, type, full, meta ){
                    return '<label class="m-checkbox m-checkbox--single m-checkbox--solid m-checkbox--brand"><input type="checkbox" value="1"><span></span></label>';
                };
                if ($.trim($(this).html()) == "") {
                    $(this).html('<label class="m-checkbox m-checkbox--single m-checkbox--all m-checkbox--solid m-checkbox--brand"><input type="checkbox"><span></span></label>');
                }
            }
            else if (columnConfig.actions) {
                columnConfig.searchable = false;
                columnConfig.orderable = false;
                columnConfig.render = buildActionBtnRender(grid, $table);
                columnConfig['class'] = "text-center";
            }
            else if(columnConfig.detailsControl){
                columnConfig.searchable = false;
                columnConfig.orderable = false;
                columnConfig['class'] = "details-control";
            }
            // support for custom column render
            var render = $(this).data("render");
            if (render && defaultRenders[render]) {
                columnConfig.render = defaultRenders[render];
            } else if (render && typeof window[render] === "function") {
                columnConfig.render = window[render];
            }
            columns[i] = columnConfig;
        });
        return columns;
    };

    var daterangeTemplate = '<div class="input-group date date-picker" data-date-format="yyyy-mm-dd">'+
        '<input type="text" class="form-control form-control-sm form-filter m-input" readonly name="#NameFrom#" placeholder="'+$.i18n.datatable.from+'">'+
        '<span class="input-group-append">'+
        '    <button class="btn btn-sm btn-secondary" type="button">'+
        '	    <i class="la la-calendar"></i>'+
        '    </button>'+
        '</span>'+
        '</div>'+
        '<div class="input-group date date-picker" data-date-format="yyyy-mm-dd">'+
        '<input type="text" class="form-control form-control-sm form-filter m-input" readonly name="#NameTo#" placeholder="'+$.i18n.datatable.to+'">'+
        '<span class="input-group-append">'+
        '    <button class="btn btn-sm btn-secondary" type="button">'+
        '	    <i class="la la-calendar"></i>'+
        '    </button>'+
        '</span>'+
        '</div>';

    var rangeTemplate = '<div class="input-group"><input type="text" class="form-control form-control-sm form-filter m-input" name="#NameFrom#" placeholder="'+$.i18n.datatable.from+'" /></div>'+
        '<div class="input-group"><input type="text" class="form-control form-control-sm form-filter m-input" name="#NameTo#" placeholder="'+$.i18n.datatable.to+'" /></div>';

    function buildAdvanceSearchFilter(grid, $table) {
        var advanceSearch = $table.data("datatable-advance-search");
        if(!advanceSearch){
            return;
        }
        // 默认是否打开高级搜索，否
        var advanceSearchShow = advanceSearch == 'show' ? true : false;
        var settings = grid.getDataTable().settings()[0];
        var hideClass = 'd-none';
        var htmlArr = [];
        htmlArr.push('<tr role="row" class="filter ' + (advanceSearchShow ? '' : hideClass) + '">');
        var inline = true;
        $.each(settings.aoColumns, function(i, columnSetting){
            var data = columnSetting;
            if (!columnSetting.bVisible) return true;
            if(data.searchable && data.data){
                var searchType = data.searchType?data.searchType:'like';
                if('daterange' == searchType){
                    var nameFrom = 'search_GE_' + data.data;
                    var nameTo = 'search_LE_' + data.data;
                    var html = daterangeTemplate;
                    html = html.replace(/#NameFrom#/g, nameFrom);
                    html = html.replace(/#NameTo#/g, nameTo);
                    htmlArr.push('<th data-index="'+i+'">'+html+'</th>');
                    inline = false;
                } else if('range' == searchType) {
                    var nameFrom = 'search_GE_' + data.data;
                    var nameTo = 'search_LE_' + data.data;
                    var html = rangeTemplate;
                    html = html.replace(/#NameFrom#/g, nameFrom);
                    html = html.replace(/#NameTo#/g, nameTo);
                    htmlArr.push('<th data-index="'+i+'">'+html+'</th>');
                    inline = false;
                } else if('like' == searchType) {
                    var name = 'search_LIKE_' + data.data;
                    htmlArr.push('<th data-index="'+i+'"><input type="text" class="form-control form-control-sm form-filter m-input" name="'+name+'"></th>');
                } else if('equal' == searchType) {
                    var name = 'search_EQ_' + data.data;
                    htmlArr.push('<th data-index="'+i+'"><input type="text" class="form-control form-control-sm form-filter m-input" name="'+name+'"></th>');
                } else if(searchType.indexOf("select:")==0){
                    var config = eval('(' + searchType.substring(7) + ')')
                    if(config){
                        var name = 'search_EQ_' + data.data;
                        htmlArr.push('<th data-index="'+i+'"><select class="form-control form-control-sm form-filter m-input" name="'+name+'">');
                        $.each(config, function(i, e){
                            htmlArr.push('<option value="'+e+'">'+i+'</option>');
                        });
                        htmlArr.push('</select></th>');
                    } else {
                        htmlArr.push('<th data-index="'+i+'">&nbsp;</th>');
                    }
                } else {
                    htmlArr.push('<th data-index="'+i+'">&nbsp;</th>');
                }
            } else if(data.actions){
                htmlArr.push('<th data-index="'+i+'" class="text-center">');
                htmlArr.push('<button class="btn btn-brand m-btn btn-sm m-btn--icon filter-submit"><span><i class="la la-search"></i><span>'+$.i18n.datatable.search+'</span></span></button>');
                htmlArr.push('<button class="btn btn-secondary m-btn btn-sm m-btn--icon filter-cancel"><span><i class="la la-close"></i><span>'+$.i18n.datatable.reset+'</span></span></button>');
                htmlArr.push('</th>');
            } else {
                htmlArr.push('<th data-index="'+i+'" >&nbsp;</th>');
            }

        });
        htmlArr.push('</tr>');

        var $heading = $table.find("thead tr.heading");
        $heading.after(htmlArr.join(''));

        inline = true; //set always inline here get best ui
        if(!inline){
            var $actionColumn = $heading.find("th data[actions]");
            if($actionColumn){
                var index = $actionColumn.index();
                $table.find('thead tr.filter th:eq('+index+') button:first').wrap('<div class="margin-bottom-5"></div>').addClass('margin-bottom');
            }
        }
        initPickers();

        var angleDownClass = 'la-angle-double-down';
        var angleUpClass = 'la-angle-double-up';
        $(".dataTables_filter", grid.getTableWrapper()).append('&nbsp;<button class="btn btn-sm btn-outline-info advance-search pull-right"><i class="la"></i> '+$.i18n.datatable.advanceSearch+'</button>');
        var icon = $(".advance-search i", grid.getTableWrapper()).addClass($("tr.filter").hasClass(hideClass)?angleDownClass:angleUpClass);
        $(".advance-search", grid.getTableWrapper()).click(function(){
            $("tr.filter").toggleClass(hideClass);
            icon.removeClass(angleDownClass).removeClass(angleUpClass).addClass($("tr.filter").hasClass(hideClass)?angleDownClass:angleUpClass);
        });
    }

    function bindCheckBoxEvent(grid, $table){
        $table.on("change","thead th input[type=checkbox]",function() {
            //event.preventDefault();
            var set = $table.find("tbody tr input[type=checkbox]");
            var checked = $(this).is(":checked");
            $(set).each(function() {
                if (checked) {
                    $(this).prop("checked", true);
                    $(this).parents('tr').addClass("active");
                } else {
                    $(this).prop("checked", false);
                    $(this).parents('tr').removeClass("active");
                }
            });
        });
        $table.on("change","tbody tr input[type=checkbox]",function() {
            //event.preventDefault();
            $(this).parents('tr').toggleClass("active");
            var set = $table.find("tbody tr input[type=checkbox]");
            var checkedSize = set.filter(":checked").length;
            var $checkAll = $table.find("thead th input[type=checkbox]");
            if(checkedSize==set.length){
                $checkAll.prop("checked", true);
            } else {
                $checkAll.prop("checked", false);
            }
        });
    }

    function buildButtonTools(grid, $table){
        // refer to: http://www.datatables.net/extensions/buttons/
        $.fn.dataTable.ext.buttons.reload = {
            action: function ( e, dt, node, config ) {
                dt.ajax.reload();
            }
        };

        $.fn.dataTable.ext.buttons.custom = {
            action: function ( e, dt, node, config ) {
            }
        };

        var buttonSettings = [];
        var $buttons = $('.table-group-actions', grid.getTableWrapper()).find("button:not(.dropdown-toggle)");
        $buttons.each(function(i, e){
            var $button = $(this);
            var data = $button.data();
            var url = data.url;
            var type = data.type ? data.type:"custom";
            var action = null;
            if(data.action && typeof window[data.action] === "function"){
                action = window[data.action];
            }
            var buttonSetting = {extend: type};
            if(action){
                buttonSetting.action = action;
            } else if(type == 'colvis'){
                buttonSetting.action = function ( e, dt, node, config ) {
                    $.fn.dataTable.ext.buttons.collection.action(e, dt, $button, config);
                    if($table.parents(".portlet").hasClass("portlet-fullscreen")){
                        var zIndex = parseInt($table.parents(".portlet").css("z-index"));
                        config._collection.css("z-index",zIndex+1);
                    }
                };
                /*buttonSetting.columnText = function ( dt, idx, title ) {
                    return (idx+1)+': '+title;
                }*/
            } else if(type == 'add') {
                buttonSetting.extend = null;
                buttonSetting.action = function ( e, dt, node, config ) {
                    window.location.href = url ? url : window.location.pathname + "/create";
                };
            } else if(type == 'edit' || type == 'update') {
                buttonSetting.type = 'edit', //update->edit
                    buttonSetting.extend = null;
                buttonSetting.action = function ( e, dt, node, config ) {
                    if (grid.getSelectedRowsCount() === 0) {
                        grid.alertNoRecordSelected();
                    } else {
                        var rowData = grid.getDataTable().rows('.active').data()[0];
                        window.location.href = url ? url.replace(/#id#/g, rowData.id) : window.location.pathname + "/" + rowData.id + "/update";
                    }
                };
            } else if(type == 'delete') {
                buttonSetting.extend = null;
                buttonSetting.action = function ( e, dt, node, config ) {
                    if (grid.getSelectedRowsCount() === 0) {
                        grid.alertNoRecordSelected();
                    } else {
                        $.m.confirm({
                            type: 'type-danger',
                            title: $.i18n.confirmToDelete,
                            message: $.i18n.confirmToDelete,
                            ok: function(){
                                var actionUrl = url ? url : window.location.pathname + "/batch/delete";
                                grid.ajax({ // define ajax settings
                                    "url": actionUrl, // ajax URL
                                    "data": { // add request parameters before submit
                                        ids : grid.getSelectedRowIds()
                                    }
                                });
                            }
                        });
                    }
                };
            }
            buttonSettings.push(buttonSetting);
            $button.on('click', function() {
                grid.getDataTable().button(i).trigger();
                $table.trigger("action.mdt.tool.button", [grid, $table, $button]);
            });
        });
        new $.fn.dataTable.Buttons(grid.getDataTable(), {
            buttons: buttonSettings
        });

        // column visible 功能需要动态增减AdvanceSearchItem
        grid.getTableContainer().on("click", ".dt-button-collection a", function () {
            var index = $(".dt-button-collection a").index($(this));
            var $filter = $table.find("thead tr.filter");
            var $th = $filter.find(" th:eq(" + index + ")");
            $th.toggle();
        });
    }

    function defaultDrawCallback(grid, $table){
        //让动态生成的内容也有工具提示效果
        $table.find('[data-toggle="m-tooltip"]').tooltip();
    }

    function initDatatable($table, options){
        var grid = new Datatable();
        $table.data("grid", grid);
        if($table.data("initialized")){
            return;
        }
        $table.data("initialized", true);

        var url = $table.data("url");
        if(!url){
            url = window.location.href;
        }

        var drawCallback = $table.data("datatable-draw-callback");
        var advanceSearch = !!$table.data("datatable-advance-search");
        var customConfig = {};
        var tableConfig = $.extend(true, {
            src: $table,
            quickSearchFilter: advanceSearch,
            dataTable: {
                "bStateSave": true,
                "ajax": {
                    "url": url, // ajax source
                },
                "columns": createColumnsOptions(grid, $table),
                "order": [],
                "customDrawCallback": function(settings){
                    defaultDrawCallback(grid, $table);
                    if(drawCallback && typeof window[drawCallback] === 'function'){
                        window[drawCallback].call(undefined, grid, $table);
                    }
                }
            }
        }, options, customConfig);
        grid.init(tableConfig);

        buildAdvanceSearchFilter(grid, $table);

        bindCheckBoxEvent(grid, $table);

        buildButtonTools(grid, $table);
        return grid;
    }

	$.m.datatable = function(options){
        var $table = $(options.src);
		return initDatatable($table, options);
	};

    $(function(){
        $('table[data-datatable="true"]').each(function() {
            var $table = $(this);
            initDatatable($table);
        });
    })
})(jQuery);